home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 46
/
Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso
/
-in_the_mag-
/
reader_requests
/
codecs
/
iff_rw.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-16
|
11KB
|
357 lines
#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/iffparse.h>
#include <graphics/gfx.h>
#include <utility/tagitem.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/iffparse.h>
#include <utility/utility.h>
#include <utility/tagitem.h>
/* Includes needed to use the codecs.library and the codecs */
#include <libraries/codecs.h>
#include <proto/codecs.h>
#include <codecs/sp.h>
#include <codecs/byterun.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "iff_rw.h"
#define ID_ILBM MAKE_ID('I','L','B','M')
#define ID_BODY MAKE_ID('B','O','D','Y')
#define ID_BMHD MAKE_ID('B','M','H','D')
#define ID_CMAP MAKE_ID('C','M','A','P')
#define NUM_STOP_CHUNKS 3
#define SET_TAGITEM(tagitem, tag, data) (tagitem).ti_Tag = (tag); (tagitem).ti_Data = (ULONG)(data)
struct Library *UtilityBase;
struct Library *CodecsBase;
static int ReadBody(struct IFFHandle *iff, BitMapHeader *bmhd, struct BitMap *bm, ULONG Size)
{
UBYTE *body;
Codec *MyCodec = NULL;
struct TagItem TagList[5];
if ((body = malloc(Size)) == NULL)
{
printf("Could not alloc body: %ld\n", Size);
return FALSE;
}
ReadChunkBytes(iff, body, Size);
printf("Compressed Size: %ld\n", Size);
printf("Bytes per Row = %d\n", bm->BytesPerRow);
/* Crete Codec to decode image */
switch (bmhd->compression)
{
case 0: printf("This ILBM picture is not compressed (not supported yet)\n"); break;
case 1: MyCodec = NewCodec("byterun.codec", 0); printf("Byterun codec\n"); break;
case 2: MyCodec = NewCodec("sp.codec", 0); printf("S+P Wavelet codec\n"); break;
default: printf("Unsupported coding method for ILBM picture\n"); break;
}
if (MyCodec)
{
SET_TAGITEM(TagList[0], CA_SRC_HANDLE, body);
SET_TAGITEM(TagList[1], CA_SRC_SIZE, Size);
SET_TAGITEM(TagList[2], CA_IMAGEWIDTH, bmhd->w);
SET_TAGITEM(TagList[3], CA_DST_HANDLE, bm);
SET_TAGITEM(TagList[4], TAG_END, 0);
Decode(MyCodec, TagList);
DisposeCodec(MyCodec);
printf("Decompressed %d bytes to %d bytes\n", Size, bm->BytesPerRow * bm->Rows * bm->Depth);
}
else
{
printf("Could not create Codec object\n");
}
free(body);
return TRUE;
}
static LONG SaveBODY(struct IFFHandle *iff, BitMapHeader *bmhd, struct BitMap *bm)
{
struct TagItem TagList[5];
ULONG BufSize = 65536;
LONG Size;
LONG ReturnValue;
UBYTE *Buffer;
Codec *MyCodec = NULL;
Buffer = malloc(BufSize);
if (Buffer)
{
switch (bmhd->compression)
{
case 0: printf("This ILBM BODY is not compressed (not supported yet)\n"); break;
case 1: MyCodec = NewCodec("byterun.codec", 0L); break;
case 2: MyCodec = NewCodec("sp.codec", 0L); break;
default: printf("Unknown compression method\n"); break;
}
if (MyCodec)
{
PushChunk(iff, ID_ILBM, ID_BODY, IFFSIZE_UNKNOWN);
SET_TAGITEM(TagList[0], CA_DST_HANDLE, Buffer);
SET_TAGITEM(TagList[1], CA_DST_SIZE, BufSize);
SET_TAGITEM(TagList[2], CA_IMAGEWIDTH, bmhd->w);
SET_TAGITEM(TagList[3], CA_SRC_HANDLE, bm);
SET_TAGITEM(TagList[4], TAG_END, 0);
Size = BufSize;
ReturnValue = 0;
while (Size == BufSize)
{
Size = Encode(MyCodec, TagList);
if (Size > 0)
{
if (WriteChunkBytes(iff, Buffer, Size) != Size)
{
printf("Could not write to IFF chunk BODY\n");
ReturnValue = -4L;
break;
}
else
{
ReturnValue += Size;
printf("Encoded %d bytes (total = %d)\n", Size, ReturnValue);
}
}
else
{
printf("Problem %d in encoder", Size);
ReturnValue = -3L;
break;
}
}
PopChunk(iff);
DisposeCodec(MyCodec);
}
else
{
ReturnValue = -2L;
}
free(Buffer);
}
else
{
ReturnValue = -1L;
}
return ReturnValue;
}
BOOL LoadILBM(char *filename, BitMapHeader *bmhd, BYTE **cmap, struct BitMap **bm)
{
struct IFFHandle *iff;
struct ContextNode *cn;
LONG StopChunkArray[NUM_STOP_CHUNKS*2] = { ID_ILBM, ID_BMHD,
ID_ILBM, ID_CMAP,
ID_ILBM, ID_BODY
};
LONG error;
*cmap = NULL;
*bm = NULL;
if ((CodecsBase = OpenLibrary("codecs.library", 0L)))
{
if ((UtilityBase = OpenLibrary(UTILITYNAME, 0L)))
{
if ((IFFParseBase = OpenLibrary("iffparse.library", 0L)))
{
if ((iff = AllocIFF()) != NULL)
{
if ((iff->iff_Stream = (ULONG)Open(filename, MODE_READWRITE)) != NULL)
{
InitIFFasDOS(iff);
OpenIFF(iff, IFFF_READ);
if ((error = StopChunks(iff, StopChunkArray, NUM_STOP_CHUNKS)))
{
printf("error with StopChunk (%d)\n", error);
return FALSE;
}
for (;;)
{
error = ParseIFF(iff, IFFPARSE_SCAN);
if (error == IFFERR_EOF)
break;
if (error)
{
printf("Error during parse %d\n", error);
return FALSE;
}
cn = CurrentChunk(iff);
if ((cn) && (cn->cn_Type == ID_ILBM))
{
switch (cn->cn_ID)
{
case ID_BMHD:
ReadChunkBytes(iff, bmhd, sizeof(*bmhd));
printf("Size: %d x %d\n", bmhd->w, bmhd->h);
printf("Planes: %d\n", bmhd->nPlanes);
printf("Compression: %d\n", bmhd->compression);
break;
case ID_CMAP:
*cmap = malloc(cn->cn_Size);
if (*cmap)
{
ReadChunkBytes(iff, *cmap, cn->cn_Size);
}
else
{
printf("Couldn't alloc memory for ColorMap\n");
}
break;
case ID_BODY:
*bm = AllocBitMap(bmhd->w, bmhd->h, bmhd->nPlanes, BMF_CLEAR, NULL);
ReadBody(iff, bmhd, *bm, cn->cn_Size);
break;
}
}
}
CloseIFF(iff);
Close(iff->iff_Stream);
}
FreeIFF(iff);
}
else
{
printf("Couldn't alloc iff handle\n");
}
CloseLibrary(IFFParseBase);
}
else
{
printf("Couldn't open iffparse.library\n");
}
CloseLibrary(UtilityBase);
}
else
{
printf("Could not open utility.library\n");
}
CloseLibrary(CodecsBase);
}
else
{
printf("Could not open codecs.library\n");
}
return TRUE;
}
LONG SaveILBM(char *filename, BitMapHeader *bmhd, BYTE *cmap, struct BitMap *bm)
{
struct IFFHandle *iff;
LONG BodySize = 0L;
if ((CodecsBase = OpenLibrary("codecs.library", 0)))
{
if ((UtilityBase = OpenLibrary(UTILITYNAME, 0L)))
{
if ((IFFParseBase = OpenLibrary("iffparse.library", 0L)))
{
if ((iff = AllocIFF()) != NULL)
{
if ((iff->iff_Stream = (ULONG)Open(filename, MODE_NEWFILE)) != NULL)
{
InitIFFasDOS(iff);
OpenIFF(iff, IFFF_WRITE);
printf("iff file is open\n");
PushChunk(iff, ID_ILBM, ID_FORM, IFFSIZE_UNKNOWN);
{
/*
* Save BMHD chunk
*/
PushChunk(iff, NULL, ID_BMHD, sizeof(*bmhd));
WriteChunkBytes(iff, bmhd, sizeof(*bmhd));
PopChunk(iff);
/*
* Save CMAP chunk when available
*/
if (cmap)
{
PushChunk(iff, NULL, ID_CMAP, 3 * (1L << bmhd->nPlanes));
WriteChunkBytes(iff, cmap, 3 * (1L << bmhd->nPlanes));
PopChunk(iff);
}
/*
* Save BODY chunk
*/
BodySize = SaveBODY(iff, bmhd, bm);
}
PopChunk(iff);
CloseIFF(iff);
Close(iff->iff_Stream);
}
FreeIFF(iff);
}
else
{
printf("Couldn't alloc iff handle\n");
}
CloseLibrary(IFFParseBase);
}
else
{
printf("Couldn't open iffparse.library\n");
}
CloseLibrary(UtilityBase);
}
else
{
printf("Could not open utility.library\n");
}
CloseLibrary(CodecsBase);
}
else
{
printf("Could not open codecs.library\n");
}
return BodySize;
}